package com.yj.timecapsule.websocket.friendChat;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONObject;
import com.yj.timecapsule.common.context.LoginUserContext;
import com.yj.timecapsule.common.utils.AsyncTaskUtil;
import com.yj.timecapsule.entity.user.Message;
import com.yj.timecapsule.mapper.MessageMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


/**
 * @author Sean
 * @CreateTime 2024-08-01  14:49
 * @Description
 * @Version 1.0
 */
@Component
@Slf4j
public class WebSocketChatHandler extends TextWebSocketHandler {
    @Resource
    private MessageMapper messageMapper;
    @Resource
    private ThreadPoolTaskExecutor databaseExecutor;
    private static final ConcurrentHashMap<Long, WebSocketSession> sessions = new ConcurrentHashMap<>();
    private static final List<Map<WebSocketSession, Long>> onlineUserIds = Collections.synchronizedList(new ArrayList<>());
    private static final Map<Long, List<String>> NOT_ONLINE_USER_MESSAGES = new ConcurrentHashMap<>();
    private static final List<String> HISTORY_MESSAGES = Collections.synchronizedList(new ArrayList<>());

    private static final List<Message> MESSAGE_LIST = Collections.synchronizedList(new ArrayList<>());
    private static final int MAX_TOTAL = 100;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        JSONObject jsonObject = new JSONObject(payload);
        long senderId = Long.valueOf(jsonObject.get("senderId").toString());
        long receiverId = Long.valueOf(jsonObject.get("receiverId").toString());
        String content = jsonObject.get("content").toString();
        log.info("收到消息：发送者ID={}, 接收者ID={}, 内容={}", senderId, receiverId, content);
        WebSocketSession receiverSession = sessions.get(receiverId);
        if (receiverSession != null && receiverSession.isOpen()) {
            receiverSession.sendMessage(new TextMessage(content));
            //  保存聊天记录
            AsyncTaskUtil.runAsync(()->{
                saveRecord(content, senderId, receiverId);
            },databaseExecutor);
        } else {
            HISTORY_MESSAGES.add(payload);
            NOT_ONLINE_USER_MESSAGES.put(receiverId, HISTORY_MESSAGES);
            log.warn("接收者ID={}的WebSocketSession不存在或已关闭,将消息添加到未在线消息列表中{}", receiverId, HISTORY_MESSAGES);
        }

    }
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Long id = LoginUserContext.getId();
        Map<WebSocketSession, Long> map = new HashMap<>();
        map.put(session, id);
        onlineUserIds.add(map);
        sessions.put(id, session);
        if (!CollectionUtil.isEmpty(NOT_ONLINE_USER_MESSAGES) && NOT_ONLINE_USER_MESSAGES.get(id) != null) {
            List<String> historyMessages = NOT_ONLINE_USER_MESSAGES.get(id);
            for (String message : historyMessages) {
                log.info("历史消息：{}", message);
                JSONObject jsonObject = new JSONObject(message);
                long senderId = Long.parseLong(jsonObject.get("senderId").toString());
                long receiverId = Long.parseLong(jsonObject.get("receiverId").toString());
                String content = jsonObject.get("content").toString();
                if (sessions.get(receiverId).equals(session)) {
                    log.info("未在线时候客户端{}发送的的历史消息:{}", senderId, content);
                    session.sendMessage(new TextMessage(content));
                    AsyncTaskUtil.runAsync(()->{
                        saveRecord(content, senderId, receiverId);
                    },databaseExecutor);
                }
            }
        }
        log.info("客户端 {} 已连接", id);
        log.info("当前连接数：{}", onlineUserIds.size());
        log.info("当前所有客户端,{}", sessions.keySet());
    }
    private void saveRecord(String content, Long senderId, Long receiverId){
        Date now = new Date();
        Message record = new Message();
        record.setContent(content);
        record.setReceiverId(receiverId);
        record.setSenderId(senderId);
        record.setSendTime(now);
        MESSAGE_LIST.add(record);
        if (MESSAGE_LIST.size() == MAX_TOTAL){
            messageMapper.insertBatch(MESSAGE_LIST);
            MESSAGE_LIST.clear();
        }
    }
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Iterator<Map<WebSocketSession, Long>> iterator = onlineUserIds.iterator();
        while (iterator.hasNext()) {
            Map<WebSocketSession, Long> map = iterator.next();
            if (map.containsKey(session)) {
                if (NOT_ONLINE_USER_MESSAGES.get(map.get(session)) != null){
                    NOT_ONLINE_USER_MESSAGES.remove(map.get(session));
                    log.info("关闭链接删除未在线时的历史消息,{}",NOT_ONLINE_USER_MESSAGES);
                }
                iterator.remove();
                sessions.remove(map.get(session));
                log.info("客户端 {} 关闭连接", map.get(session));
                log.info("当前连接数:{}", sessions.size());
                break;
            }
        }

    }



}
